package com.code.generate;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ModelGenerator {
    private static String preModelPath = "D:\\out\\前台Model\\";
    private static String backModelPath = "D:\\out\\后台Model\\";

    /**
     * @description: <方法描述>
     * @param args
     */
    public static void main(String[] args) {
        updateFieldToNull();
        // String schema = "MANAGER";
        // List<Map<String, Object>> tables = getTables(schema);
        // for (Map<String, Object> table : tables) {
        // genModelCode("" + table.get("NAME"), table.get("REMARKS"), schema);
        // // genPreModelCode("" + table.get("NAME"), table.get("REMARKS"), schema);
        // }
    }

    /**
     * <方法描述>更新系统值，空串改为null
     * 
     * @example <调用范例>
     */
    public static void updateFieldToNull() {
        String[] schemas = { "MANAGER", "MOBILE", "CMS", "BOSS", "BIZ" };
        String[] dbs = { "GMCC_UTF", "GMCC", "GMCC_UTF", "GMCC", "GMCC" };
        for (int i = 0; i < schemas.length; i++) {
            String schema = schemas[i];
            ConnectionUtil util = new ConnectionUtil("com.ibm.db2.jcc.DB2Driver", "jdbc:db2://10.200.48.172:50000/"
                    + dbs[i], "db2inst1", "db2inst1");
            String sql = "SELECT NAME from sysibm.systables where creator = '" + schema + "'";
            List<Map<String, Object>> resultList = util.executeQuery(sql);
            for (Map<String, Object> map : resultList) {
                String table = (String) map.get("NAME");
                String colSql = "select NAME from sysibm.syscolumns where TBNAME='" + table + "' and tbCREATOR = '"
                        + schema + "' and coltype='VARCHAR'";
                List<Map<String, Object>> colList = util.executeQuery(colSql);
                for (Map<String, Object> col : colList) {
                    String colName = (String) col.get("NAME");
                    String updSql = "UPDATE " + schema + "." + table + " set " + colName + "=null where " + colName
                            + "=''";
                    boolean success = util.update(updSql);
                    if (!success) {
                        System.out.println(updSql);
                    }
                }
            }
        }
    }

    private static List<Map<String, Object>> getTables(String schema) {
        String sql = "SELECT NAME,REMARKS from sysibm.systables where creator = '" + schema + "'";
        ConnectionUtil util = new ConnectionUtil("com.ibm.db2.jcc.DB2Driver", "jdbc:db2://10.200.50.161:50000/GMCC161",
                                                 "db2inst1", "db2inst1");
        List<Map<String, Object>> resultList = util.executeQuery(sql);
        return resultList;
    }

    private static List<Field> getColumns(String tableName, String schema) {
        String sql = "select NAME,TBNAME,TBCREATOR,REMARKS,COLTYPE,NULLS,LENGTH,KEYSEQ from sysibm.syscolumns where TBNAME='"
                + tableName + "' AND tbCREATOR='" + schema + "' order by colno";
        ConnectionUtil util = new ConnectionUtil("com.ibm.db2.jcc.DB2Driver", "jdbc:db2://10.200.50.161:50000/GMCC161",
                                                 "db2inst1", "db2inst1");
        List<Field> resultList = new ArrayList<Field>();
        for (Map<String, Object> map : util.executeQuery(sql)) {
            resultList.add(new Field(map));
        }
        return resultList;
    }

    /**
     * 生成后台Model
     * 
     * @description: <方法描述>
     * @param tableName
     * @param tableRemark
     * @param schema
     */
    public static void genModelCode(String tableName, Object tableRemark, String schema) {
        String className = CommonUtils.changeFirstUpper(CommonUtils.getProperty(tableName));
        StringBuffer fieldCode = new StringBuffer();
        StringBuffer getSetFunc = new StringBuffer();
        Map<String, String> importPackage = new HashMap<String, String>();
        StringBuffer code = new StringBuffer();
        List<Field> fields = getColumns(tableName, schema);
        fieldCode.append("    private static final long serialVersionUID = 1L;\n");
        for (Field field : fields) {
            // 过滤生成创建时间、创建人、修改时间、修改人等4个字段
            if ("createTime".equals(field.getFieldName()) || "creator".equals(field.getFieldName())
                    || "editTime".equals(field.getFieldName()) || "editor".equals(field.getFieldName())) {
                continue;
            }
            if (field.getRemark() != null) {
                fieldCode.append("    /**\n");
                fieldCode.append("     * " + field.getRemark() + "\n");
                fieldCode.append("     */\n");
            }
            if (field.isWhetherPrimaryKey()) {
                fieldCode.append("    @Id\n");
            }
            fieldCode.append("    @Column(name = \"" + field.getTableField() + "\"");
            if (field.isWhetherRequest()) {
                fieldCode.append(" ,nullable = false");
            }
            if (field.isUnique()) {
                fieldCode.append(" , unique = true");
            }
            if (field.getLength() > 0) {
                fieldCode.append(" , length = " + field.getLength() + "");
            }
            fieldCode.append(")\n");
            if (field.isWhetherPrimaryKey()) {
                fieldCode.append("    @GenerateValue(strategy = GenerateType.AUTO)\n");
            }
            fieldCode.append("    private ").append(field.getFieldType()).append(" ").append(field.getFieldName()).append(";\n");
            fieldCode.append("\n");
            // getter
            getSetFunc.append("    public ");
            getSetFunc.append(field.getFieldType());
            if ("boolean".equals(field.getFieldType()) || "Boolean".equals(field.getFieldType())) {
                getSetFunc.append(" " + field.getFieldName());
            } else {
                getSetFunc.append(" get");
                getSetFunc.append(CommonUtils.changeFirstUpper(field.getFieldName()));
            }
            getSetFunc.append("(){\n        return this.");
            getSetFunc.append(field.getFieldName());
            getSetFunc.append(";\n    }\n\n");
            // setter
            getSetFunc.append("    public void ");
            if ("boolean".equals(field.getFieldType()) || "Boolean".equals(field.getFieldType())) {
                getSetFunc.append(field.getFieldName().replaceFirst("is", "set"));
            } else {
                getSetFunc.append("set");
                getSetFunc.append(CommonUtils.changeFirstUpper(field.getFieldName()));
            }
            getSetFunc.append("(");
            getSetFunc.append(field.getFieldType());
            getSetFunc.append(" ").append(field.getFieldName());
            getSetFunc.append("){\n        this.");
            getSetFunc.append(field.getFieldName());
            getSetFunc.append(" = ").append(field.getFieldName());
            getSetFunc.append(";\n    }\n\n");
            if ("BigDecimal".equals(field.getFieldType())) {
                importPackage.put("BigDecimal", "import java.math.BigDecimal;\n");
            } else if ("DateTime".equals(field.getFieldType())) {
                importPackage.put("DateTime", "import com.dzqd.jaf.core.lang.DateTime;\n");
            } else if ("Time".equals(field.getFieldType())) {
                importPackage.put("Time", "import com.dzqd.jaf.core.lang.Time;\n");
            } else if ("Timestamp".equals(field.getFieldType())) {
                importPackage.put("Timestamp", "import com.dzqd.jaf.core.lang.Timestamp;\n");
            }
        }
        code.append("package com.gd10086.management.model.sys;\n");
        code.append("\n");
        code.append("import javax.persistence.Column;\n");
        code.append("import javax.persistence.Entity;\n");
        code.append("import javax.persistence.Id;\n");
        code.append("import javax.persistence.Table;\n");
        code.append("\n");
        code.append("import com.dzqd.jaf.jdbc.annotation.EntityJNDI;\n");
        code.append("import com.dzqd.jaf.jdbc.annotation.GenerateValue;\n");
        code.append("import com.dzqd.jaf.jdbc.tag.GenerateType;\n");
        code.append("import com.gd10086.management.annotation.TargetJDNI;\n");
        code.append("import com.gd10086.management.model.ManagementModel;\n");
        code.append("\n");
        for (String str : importPackage.values())
            code.append(str);
        code.append("\n");
        if (tableRemark != null && !"".equals(tableRemark)) {
            code.append("/**\n");
            code.append(" * " + tableRemark + "\n");
            code.append(" */\n");
        }
        code.append("@Entity\n");
        code.append("@Table(name = \"" + tableName + "\", schema = \"" + schema + "\")\n");
        code.append("@EntityJNDI(TargetJDNI.GMCC_UTF)\n");
        code.append("public class " + className + " extends ManagementModel {\n");
        code.append("\n");
        code.append(fieldCode);
        code.append("\n");
        // code.append("    public " + className + "() {\n    }\n");
        // code.append("\n");
        code.append(getSetFunc);
        code.append("}");
        FileOutputStream fos;
        String filePath = backModelPath + className + ".java";
        try {
            File f = new File(filePath);
            if (!f.getParentFile().exists()) {
                f.getParentFile().mkdirs();
            }
            if (!f.exists()) {
                f.createNewFile();
            }
            fos = new FileOutputStream(f);
            Writer out = new OutputStreamWriter(fos, "UTF-8");
            out.write(code.toString());
            out.close();
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 生成前台Model
     * 
     * @description: <方法描述>
     * @param tableName
     * @param tableRemark
     * @param schema
     */
    public static void genPreModelCode(String tableName, Object tableRemark, String schema) {
        String className = CommonUtils.changeFirstUpper(CommonUtils.getProperty(tableName));
        StringBuffer fieldCode = new StringBuffer();
        StringBuffer getSetFunc = new StringBuffer();
        Map<String, String> importPackage = new HashMap<String, String>();
        StringBuffer code = new StringBuffer();
        List<Field> fields = getColumns(tableName, schema);
        fieldCode.append("    private static final long serialVersionUID = 1L;\n");
        for (Field field : fields) {
            // 过滤生成创建时间、创建人、修改时间、修改人等4个字段
            if ("createTime".equals(field.getFieldName()) || "creator".equals(field.getFieldName())
                    || "editTime".equals(field.getFieldName()) || "editor".equals(field.getFieldName())) {
                continue;
            }
            if (field.getRemark() != null) {
                fieldCode.append("    /**\n");
                fieldCode.append("     * " + field.getRemark() + "\n");
                fieldCode.append("     */\n");
            }
            fieldCode.append("    @ColumnInfo(name = \"" + field.getTableField() + "\")\n");
            fieldCode.append("    private ").append(field.getFieldType()).append(" ").append(field.getFieldName()).append(";\n");
            fieldCode.append("\n");
            // getter
            getSetFunc.append("    public ");
            getSetFunc.append(field.getFieldType());
            getSetFunc.append(" get");
            getSetFunc.append(CommonUtils.changeFirstUpper(field.getFieldName()));
            getSetFunc.append("(){\n        return this.");
            getSetFunc.append(field.getFieldName());
            getSetFunc.append(";\n    }\n\n");
            // setter
            getSetFunc.append("    public void set");
            getSetFunc.append(CommonUtils.changeFirstUpper(field.getFieldName()));
            getSetFunc.append("(");
            getSetFunc.append(field.getFieldType());
            getSetFunc.append(" ").append(field.getFieldName());
            getSetFunc.append("){\n        this.");
            getSetFunc.append(field.getFieldName());
            getSetFunc.append(" = ").append(field.getFieldName());
            getSetFunc.append(";\n    }\n\n");
            if ("BigDecimal".equals(field.getFieldType())) {
                importPackage.put("BigDecimal", "import java.math.BigDecimal;\n");
            } else if ("Date".equals(field.getFieldType())) {
                importPackage.put("Date", "import java.util.Date;\n");
            } else if ("Time".equals(field.getFieldType())) {
                importPackage.put("Date", "import java.sql.Time;\n");
            } else if ("Timestamp".equals(field.getFieldType())) {
                importPackage.put("Date", "import java.sql.Timestamp;\n");
            }
        }
        code.append("package com.gd10086.portal.model.mall;\n");
        code.append("\n");
        code.append("import com.jaf.platform.persistence.jdbc.annotations.ColumnInfo;\n");
        code.append("import com.jaf.platform.persistence.jdbc.annotations.EntityInfo;\n");
        code.append("import com.jaf.platform.persistence.jdbc.annotations.Operation;\n");
        code.append("import com.jaf.platform.persistence.jdbc.annotations.Operations;\n");
        code.append("\n");
        for (String str : importPackage.values())
            code.append(str);
        code.append("\n");
        if (tableRemark != null && !"".equals(tableRemark)) {
            code.append("/**\n");
            code.append(" * " + tableRemark + "\n");
            code.append(" */\n");
        }
        code.append("@EntityInfo(name = \"" + tableName + "\", schema = \"" + schema + "\")\n");
        code.append("@Operations({\n");
        code.append("    @Operation(name=\"get" + className
                + "\", sql=\"SELECT * FROM $tableName WHERE SID = ? with ur\")\n");
        code.append("})\n");
        code.append("public class " + className + " extends MallBaseModel {\n");
        code.append("\n");
        code.append(fieldCode);
        code.append("\n");
        code.append("    public " + className + "() {\n    }\n");
        code.append("\n");
        code.append(getSetFunc);
        code.append("\n");
        code.append("}\n");
        FileOutputStream fos;
        String filePath = preModelPath + className + ".java";
        try {
            File f = new File(filePath);
            if (!f.getParentFile().exists()) {
                f.getParentFile().mkdirs();
            }
            if (!f.exists()) {
                f.createNewFile();
            }
            fos = new FileOutputStream(f);
            Writer out = new OutputStreamWriter(fos, "GBK");
            out.write(code.toString());
            out.close();
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
